package com.qf.qfcenterservice.api;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qf.common.bean.R;
import com.qf.common.dto.DeviceDto;
import com.qf.common.dto.ProductDto;
import com.qf.common.feigns.DeviceApi;
import com.qf.common.feigns.DeviceTypeApi;
import com.qf.common.model.QfDevice;
import com.qf.common.model.QfDeviceType;
import com.qf.common.model.QfProduct;
import com.qf.qfcenterservice.service.DeviceService;
import com.qf.qfcenterservice.service.DeviceTypeService;
import com.qf.qfcenterservice.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

@RestController
@Slf4j
public class DeviceFeignApi implements DeviceApi {

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private ProductService productService;

    @Autowired
    private DeviceTypeService deviceTypeService;



    @GetMapping("/api/device/count/{tenantId}/{deleted}")
    @Override
    public R count(@PathVariable("tenantId") Long tenantId, @PathVariable("deleted") int deleted) {

        Wrapper<QfDevice> qw = Wrappers.lambdaQuery(QfDevice.class)
                .eq(QfDevice::getTenantId,tenantId)
                .eq(QfDevice::getDeleted,deleted);

        long count = deviceService.count(qw);

        log.info("---- deviceCount: {}",count);

        Map map = new HashMap();
        map.put("allCount",count);

        return R.ok(map);
    }

    @GetMapping("/api/device/listByTenant/{tenantId}")
    public R listByTenant(@PathVariable("tenantId") Long tenantId) throws ExecutionException, InterruptedException {

        Wrapper<QfDevice> qw = Wrappers.lambdaQuery(QfDevice.class)
                .eq(QfDevice::getTenantId,tenantId)
                .eq(QfDevice::getDeleted,0);

        List<QfDevice> qfDevices = deviceService.list(qw);

        //页面需要的信息除了QfDevice外，还有productName、productKey、deviceType、deviceTypeName,所以返回的QfDeviceDto
        List<DeviceDto> deviceDtos = Collections.synchronizedList(new ArrayList<>());
        List<CompletableFuture<Void>> futureList = new ArrayList<>();
        qfDevices.forEach(device->{
            Long productId = device.getProductId();
            Long deviceTypeId = device.getDeviceTypeId();
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                DeviceDto deviceDto = new DeviceDto();
                deviceDto.convertDoToDto(device);

                //根据productId查询product
                QfProduct product = productService.getById(productId);
                deviceDto.setProductName(product.getName());
                deviceDto.setProductKey(product.getProductKey());

                //根据deviceTypeId查询deviceType
                QfDeviceType deviceType = deviceTypeService.getById(deviceTypeId);
                deviceDto.setDeviceType(deviceType.getDeviceType()+"");
                deviceDto.setDeviceTypeName(deviceType.getName());

                //添加到deviceDtos
                deviceDtos.add(deviceDto);
            });
            futureList.add(future);
        });

        //阻塞等待所有dto都获取完成
        CompletableFuture.allOf(futureList.toArray(new CompletableFuture[0])).get();

        //根据设备创建时间倒序排序,防止顺序随机变化
        Collections.sort(deviceDtos, (o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()));

//        deviceDtos.forEach(System.out::println);

        return R.ok(deviceDtos);
    }

    @GetMapping("/api/device/get/{deviceId}")
    public R get(@PathVariable("deviceId") Long deviceId){
        QfDevice device = deviceService.getById(deviceId);

        Long productId = device.getProductId();
        Long deviceTypeId = device.getDeviceTypeId();

        DeviceDto deviceDto = new DeviceDto();
        deviceDto.convertDoToDto(device);

        //根据productId查询product
        QfProduct product = productService.getById(productId);
        deviceDto.setProductName(product.getName());
        deviceDto.setProductKey(product.getProductKey());

        ProductDto productDto = new ProductDto();
        productDto.convertDoToDto(product);
        deviceDto.setProductDto(productDto);

        //根据deviceTypeId查询deviceType
        QfDeviceType deviceType = deviceTypeService.getById(deviceTypeId);
        deviceDto.setDeviceType(deviceType.getDeviceType()+"");
        deviceDto.setDeviceTypeName(deviceType.getName());

        return R.ok(deviceDto);
    }

    @Override
    public String getTenantIdByDeviceKey(String deviceKey) {
        QfDevice device = deviceService.getOne(Wrappers.lambdaQuery(QfDevice.class).eq(QfDevice::getDeviceKey, deviceKey));
        return device.getTenantId();
    }

    @Override
    public String getProductKeyByDeviceKey(String deviceKey) {
        QfDevice device = deviceService.getOne(Wrappers.lambdaQuery(QfDevice.class).eq(QfDevice::getDeviceKey, deviceKey));
        Long productId = device.getProductId();

        //根据productId查询productKey
        QfProduct product = productService.getById(productId);
        return product.getProductKey();
    }

    @Override
    public QfDevice findByDeviceKey(String deviceKey) {
        return deviceService.getOne(Wrappers.lambdaQuery(QfDevice.class).eq(QfDevice::getDeviceKey, deviceKey));
    }
}
